package com.lin.controller;

import cn.hutool.bloomfilter.BitMapBloomFilter;
import cn.hutool.bloomfilter.BloomFilter;
import cn.hutool.bloomfilter.BloomFilterUtil;
import cn.hutool.core.util.HashUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lin.domain.Chain;
import com.lin.domain.common.AjaxResult;
import com.lin.domain.global.BitMap;
import com.lin.mapper.ChainMapper;
import com.lin.utils.DecimalUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

@RestController
@RequestMapping("")
public class ShortChainController {
    @Resource
    private ChainMapper chainMapper;

    /**
     * 长链->短链
     * @param longChain 长链
     */
    @PostMapping("/shortChain")
    public AjaxResult create(@RequestParam String longChain){
        // 原始长链,可加上用户的id
        String oldLongChain = longChain;
        // 查询数据库或者redis看是否已经生成过
        Chain chain1 = chainMapper.selectOne(new LambdaQueryWrapper<Chain>().eq(Chain::getLongChain, oldLongChain));
        if(ObjectUtil.isNotNull(chain1)){
            return AjaxResult.success(chain1.getShortChain());
        }
        // 布隆过滤器,全局变量,项目启动时将数据库短链都放到布隆里
        BitMapBloomFilter bitMap = BitMap.getShortChainMap();
        String shortChain;
        while(true){
            // 计算出长链的hash
            int fnvHash = HashUtil.fnvHash(longChain);
            // 10进制转62进制短链字符串 "1eDpPm"
            shortChain = DecimalUtil.decimalTo62Base(fnvHash);
            if(bitMap.contains(shortChain)){
                longChain += RandomUtil.randomString(1);
            } else {
                bitMap.add(shortChain);
                break;
            }
        }

        // 保存到数据库
        Chain chain = new Chain(oldLongChain,shortChain);
        chainMapper.insert(chain);
        return AjaxResult.success(shortChain);
    }

    /**
     * 短链重定向
     */
    @GetMapping("/a/{shortChain}")
    public void query(@PathVariable String shortChain, HttpServletResponse response) {
        // 数据库查询对应长链
        Chain chain = chainMapper.selectOne(new LambdaQueryWrapper<Chain>().eq(Chain::getShortChain, shortChain));
        String longChain = chain.getLongChain();
        //编码,防止url有中文
        String encodeLongChain = URLUtil.encode(longChain);
        // 拼接域名、端口、访问文件前缀
        String url = "http://localhost:19090/file/common"+encodeLongChain;
        //重定向
        //response.sendRedirect(encodeUrl);
        response.setStatus(302);
        response.setHeader("location",url);
    }
}
